package handler

import (
	"github.com/gin-gonic/gin"
	"internal/codec"
	"net/http"
	"reflect"
	"strconv"
)

// ApiResult 接口返回结果
type ApiResult struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

// NewApiResult 实例化结果
func NewApiResult() *ApiResult {
	return &ApiResult{
		Code: 0,
		Msg:  "success!",
		Data: gin.H{},
	}
}

// WrapHandlerFunc 定义一个直接返回api结果的
type WrapHandlerFunc func(*gin.Context) *ApiResult

func WrapHandler(handler WrapHandlerFunc) gin.HandlerFunc {
	return func(c *gin.Context) {
		result := handler(c)
		if result != nil {
			// 获取结果类型
			dataType := reflect.TypeOf(result.Data)
			// 定义存储二进制文件流变量
			var stream []byte
			// 对返回结果不同类型进行处理
			switch dataType.Kind() {
			// 字符串类型,将data转换为二进制文件流
			case reflect.String:
				stream = []byte(result.Data.(string))
			// 切片类型
			case reflect.Slice:
				stream = result.Data.([]byte)
			default:
				// 默认使用json序列化转成二进制流
				stream, _ = codec.JsonMarshal(result)
			}
			c.Header("Content-Length", strconv.Itoa(len(stream)))
			c.Data(http.StatusOK, "application/json;charset=utf-8", stream)
		} else {
			c.JSON(http.StatusOK, gin.H{
				"code": -1,
				"msg":  "500 service error!",
			})
		}
	}
}

// WrapHandlerFuncV2 定义返回一个泛型的结果
type WrapHandlerFuncV2 func(*gin.Context) interface{}

/*
在Gin框架中，c.Data 是一个方法，它用于向客户端发送响应数据。这个方法允许你指定HTTP响应的状态码、内容类型以及要发送的数据。c.Data 方法通常用于发送简单的数据响应，比如文本、JSON或二进制文件。
*/

func WrapHandlerV2(handler WrapHandlerFuncV2) gin.HandlerFunc {
	return func(c *gin.Context) {
		result := handler(c)
		if result != nil {
			dataType := reflect.TypeOf(result)
			var stream []byte
			switch dataType.Kind() {
			case reflect.String:
				stream = []byte(result.(string))
			case reflect.Slice:
				stream = result.([]byte)
			default:
				stream, _ = codec.JsonMarshal(result)
			}
			c.Header("Content-Length", strconv.Itoa(len(stream)))
			c.Data(http.StatusOK, "application/json;charset=utf-8", stream)
		} else {
			c.JSON(http.StatusOK, gin.H{
				"code": -1,
				"msg":  "500 service error!",
			})
		}
	}
}
